﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

namespace Frogism.Core {
  public class Book : ObjectIdBase, IBook{
    public virtual int Priority { get; set; }
    public virtual string Title {
      get;
      set;
    }
    public virtual int GenreId { get { return 1; } set { } }
    public virtual int Rating { get { return 1; } set { } }
    public virtual int GoalYear { get; set; }
    private bool _IsFinished;
    public virtual bool IsFinished {
      get{
        return _IsFinished || (this.LastPageNumber > 0 && this.ToGo == 0);
      }
      set{
        _IsFinished = value;
      } 
    
    }
    public virtual IAuthor Author {
      get;
      set;
    }

    public virtual int TotalPages {
      get {
        return LastPageNumber + IndexLength;
      }
    }

    public virtual int LastPageNumber {
      get;
      set;
    }


    public virtual int LastYearRead
    {
        get
        {
            int v = ReadBy((new DateTime(DateTime.Now.Year, 1, 1, 0, 0, 0)).AddDays(-1));
            return v;
        }
    }
    public virtual int CurrentPage {
      get {
          return ReadBy(DateTime.Now);
      }
    }

    public virtual int ToGo {
      get {
        return TotalPages - CurrentPage;
      }
    }
    public virtual double PercentRead {
      get {


        return (double)ReadBy(DateTime.Now, true) / (double)TotalPages * 100.0;
      }
    }


    public virtual void SetReads(Collection<IRead> reads) {
      this._Reads = reads;
    }
    private IList<IRead> _Reads;
    public virtual IList<IRead> Reads {
      get {
        if(_Reads == null) {
          _Reads = new Collection<IRead>();
        }
        return _Reads;
      }
      set {
        _Reads = value;
      }
    }
    public virtual int TotalRead
    {
        get
        {
              return CurrentPage;
        }
    }
    public virtual double ActualPage {
        get
        {
        return Factor * ReadBy(DateTime.Now,false);
        }
    }
    public virtual int IndexLength
    {
        get;
        set;
    }
    private double _Factor = 1;
    public virtual  double Factor
    {
        get
        {
            return _Factor;
        }
        set
        {
            if (value == null || value <= 0)
            {
                _Factor = 1;
            }else{
                _Factor = value;
            }
        }
    }
    public virtual int ReadBy(DateTime date) {
      return ReadBy(date, true);
    }
    public virtual int ReadBy(DateTime date, bool includeIndex)
    {
        IEnumerable<IRead> reads = Reads.Where(c => c.ReadDate <= date);
        if (reads.Count() > 0)
        {
          return reads.Max(c => c.Page)+ (includeIndex?IndexLength:0);
        }
        else
        {
            return 0;
        }
    }
    public virtual DateTime LastReadDate {
      get{
        if (Reads.Count() == 0)
          return DateTime.MinValue;
        return Reads.Max(c =>c.ReadDate);
      
      }
    }
    public virtual int YearRead
    {
        get
        { 
            IEnumerable<IRead> reads = Reads.Where(c => c.ReadDate.Year == DateTime.Now.Year);
            if (reads.Count() > 0)
            {
                return TotalRead - LastYearRead;
            }
            else
            {
                return 0;
            }
        }
    }
    public virtual bool WasReadToday {
      get {
        return Reads.Where(r => r.ReadDate.CleanDate() == DateTime.Now.CleanDate()).Count() > 0;
      }
    }
    public virtual bool IsPrivate { get; set; }
  }
}
